package com.desksoft.ecommerce.handler.servlet;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.desksoft.ecommerce.util.remoteio.RemoteIOUtil;
import com.desksoft.ecommerce.vo.AttachVO;
import com.desksoft.utility.cache.ICache;
import com.desksoft.utility.date.DateUtil;
import com.desksoft.utility.exception.PermitException;
import com.desksoft.utility.file.FileNameUtil;
import com.desksoft.utility.file.FileUtil;
import com.desksoft.utility.file.IOUtil;
import com.desksoft.utility.request.RequestUtil;
import com.desksoft.utility.string.StringUtil;

/***************************************
 * 版权所有：杭州迪科软件 保留所有权利
 * 创建日期: 
 * 创建作者：luoy
 * 文件名称：上传Servlet
 * 版本：
 * 功能：
 * 最后修改时间：
 * 修改记录：
 *****************************************/
public class UploadServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 125630820429050308L;
	
	public static final String KEY = "uploadList";
	protected RemoteIOUtil remoteIOUtil;
	protected ICache memcache;
	
	private static final Log logger = LogFactory.getLog(UploadServlet.class);
	
	/**
	 * 	获取存放文件名列表的Key
	 *	userId_persId_uploadList
	 */
	protected String getKey(HttpServletRequest req){
		return req.getParameter("userid") + "_" + req.getParameter("persid") + "_" + req.getParameter("sessionId") + "_" + KEY;
	}
	
	/**
	 * 上传功能
	 * @requestparameter	sessionId	
	 * @requestparameter	path		文件路径（远程路径传rootDir以后的路径）	
	 * 
	 * @requestparameter	filenametype	文件名称类型
	 * 										random(默认)随机文件名
	 * 										appoint	指定文件名
	 * 										original 原始文件名
	 * @requestparameter	filename		当文件名称类型指定为appoint的时候用于获取文件名
	 */
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		if (logger.isDebugEnabled()) {
            logger.debug("doGet(HttpServletRequest, HttpServletResponse) - start"); //$NON-NLS-1$
        }
		
		for (Enumeration<String> e=req.getParameterNames();e.hasMoreElements();){
			String key = e.nextElement();
			logger.debug("key:"+key+"\t\tvalue:"+req.getParameter(key));
		}
		logger.debug(req.getMethod());
		
		List<FileItem> fileItemList = null;
		
		try {
			fileItemList = RequestUtil.getUploadFileList(req);
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
		
		List<AttachVO> attachList = new ArrayList<AttachVO>();
		AttachVO attach = null;
		String itemName,randomName;
		File tempFile;
		String path = req.getParameter("path");
		String tempPath = "";
		if (!this.remoteIOUtil.exists(path)){
			String split = "/";
			String[] subpaths = StringUtil.splitter(split, 
					StringUtils.substringBeforeLast(checkNotNull(path), split));
			
			String subpath = null;
			for (String p : subpaths) {
				subpath = ((subpath == null) ? p : (StringUtil.join(subpath, split, p)));
				if (this.remoteIOUtil.exists(subpath)) {
					continue;
				}
				
				this.remoteIOUtil.mkDir(subpath);
			}
//			this.remoteIOUtil.mkDir(path);
//			this.remoteIOUtil.mkDir(path);
		}
		if (!path.endsWith("/")){
			path = path + "/";
		}
		
		for (FileItem item : fileItemList) {
			if (item.isFormField()||this.isNoUpload(item.getName(), req)){
				continue;
			}
			
			itemName = item.getName();
			
			/**
			 * 如果文件名本身带有路径信息则保留
			 */
			if (itemName.indexOf("/")!=-1){
				int index = itemName.lastIndexOf("/");
				tempPath = itemName.substring(0, (index>0)?index:0);
				if (!tempPath.endsWith("/")){tempPath = tempPath + "/";}
			}
			
			randomName = this.getFileName(itemName, req);
			randomName  = tempPath +randomName;
			tempFile = new File(path, randomName);
			
			attach = new AttachVO();
			attach.setFileName(itemName);
			attach.setFileSize(item.getSize());
			attach.setMorKB(FileUtil.getFileSizeSum(attach.getFileSize()));
			attach.setTempPath(tempFile.getAbsolutePath());
			attach.setNewName(tempFile.getName());
			attach.setTempUrl(path + randomName);
			attach.setRelativePath(path + randomName);
			
			uploadFile(attach.getRelativePath(),item.getInputStream());
			
			attachList.add(attach);
		}
		
		if (memcache.keyExists(getKey(req))){
			memcache.delete(getKey(req));
		}
		memcache.add(getKey(req), attachList,DateUtil.addDateSecond(new Date(), 60 * 60));
	}
	
	/**
	 * 检测该文件名是否不需要上传
	 * @return true 	不需要上传
	 */
	public boolean isNoUpload(String fileName,HttpServletRequest request){
		String res=request.getParameter(fileName);
		return "false".equals(res);
	}
	
	/**
	 * 获取文件名
	 */
	public String getFileName(String itemName,HttpServletRequest request){
		String ext="";
		try {
			ext = FileNameUtil.getExt(itemName);
		} catch (PermitException e) {
			e.printStackTrace();
		}
		
		String filenametype = request.getParameter("filenametype");
		
		if ("appoint".equals(filenametype)){
			return request.getParameter("filename");
		}else if ("original".equals(filenametype)){
			return itemName;
		}
		else{
			String randomName = FileNameUtil.getRandomIntegerName(7);
			String time = System.currentTimeMillis()+"";
			randomName = randomName + time.substring(time.length()-3)+"."+ext;
			return randomName;
		}
		
		
	}
	
	/**
	 * 上传文件
	 * @return
	 * @throws IOException 
	 */
	public void uploadFile(String path,InputStream inputStream) throws IOException{
		OutputStream outputStream = remoteIOUtil.getOutputStream(path);
		IOUtil.writeToOutputStreamBufferSizeFlush(inputStream, outputStream);
		outputStream.close();
	}

	public RemoteIOUtil getRemoteIOUtil() {
		return remoteIOUtil;
	}

	public void setRemoteIOUtil(RemoteIOUtil remoteIOUtil) {
		this.remoteIOUtil = remoteIOUtil;
	}

	public ICache getMemcache() {
		return memcache;
	}

	public void setMemcache(ICache memcache) {
		this.memcache = memcache;
	}

	
}
